﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Data.OleDb;
using System.Collections.ObjectModel;
using System.Windows.Forms;
using PrjSerails;

namespace SS_SocketServer
{
    public class OperProcess
    {
        public TSocketServerBase<TTestSession, TTestAccessDatabase> m_socketServer;

        public delegate void ShowErrorMsg(string msg); //声明委托
        public event ShowErrorMsg showErrorMsg;


        //数据报上限
        int maxDatagramSize = 100;

        public OperProcess()
        {

        }


        //启动服务器
        public void StartSocketServer()
        {

            bool r = false;
            m_socketServer = new TSocketServerBase<TTestSession, TTestAccessDatabase>();

            m_socketServer.MaxDatagramSize = 1024 * maxDatagramSize;

            this.AttachServerEvent();  // 附加服务器全部事件
            r = m_socketServer.Start();


        }

        /// <summary>
        /// 停止服务器
        /// </summary>
        public void StopSockerServer()
        {
            m_socketServer.Stop();
            m_socketServer.Dispose();

        }
        /// <summary>
        /// 暂停服务器
        /// </summary>
        public void PauseSocketServer()
        {
            m_socketServer.PauseListen();

        }

        /// <summary>
        /// 
        /// </summary>
        public void ResumeSocketServer()
        {
            m_socketServer.ResumeListen();

        }


        //附加服务器全部事件
        private void AttachServerEvent()
        {
            m_socketServer.ServerStarted += this.SocketServer_Started;
            m_socketServer.ServerClosed += this.SocketServer_Stoped;
            m_socketServer.ServerListenPaused += this.SocketServer_Paused;
            m_socketServer.ServerListenResumed += this.SocketServer_Resumed;
            m_socketServer.ServerException += this.SocketServer_Exception;

            m_socketServer.SessionRejected += this.SocketServer_SessionRejected;
            m_socketServer.SessionConnected += this.SocketServer_SessionConnected;
            m_socketServer.SessionDisconnected += this.SocketServer_SessionDisconnected;
            m_socketServer.SessionReceiveException += this.SocketServer_SessionReceiveException;
            m_socketServer.SessionSendException += this.SocketServer_SessionSendException;

            m_socketServer.DatagramDelimiterError += this.SocketServer_DatagramDelimiterError;
            m_socketServer.DatagramOversizeError += this.SocketServer_DatagramOversizeError;
            m_socketServer.DatagramAccepted += this.SocketServer_DatagramReceived;
            m_socketServer.DatagramError += this.SocketServer_DatagramrError;
            m_socketServer.DatagramHandled += this.SocketServer_DatagramHandled;

            m_socketServer.ShowDebugMessage += this.SocketServer_ShowDebugMessage;
        }


        #region 服务器事件
        private void SocketServer_Started(object sender, EventArgs e)
        {
            this.AddInfo("Server started at: " + DateTime.Now.ToString());
        }

        private void SocketServer_Stoped(object sender, EventArgs e)
        {
            this.AddInfo("Server stoped at: " + DateTime.Now.ToString());
        }

        private void SocketServer_Paused(object sender, EventArgs e)
        {
            this.AddInfo("Server paused at: " + DateTime.Now.ToString());
        }

        private void SocketServer_Resumed(object sender, EventArgs e)
        {
            this.AddInfo("Server resumed at: " + DateTime.Now.ToString());
        }

        private void SocketServer_Exception(object sender, TExceptionEventArgs e)
        {
            this.AddInfo("Server exception: " + e.ExceptionMessage);
            showErrorMsg("Server exception: " + e.ExceptionMessage);
        }

        private void SocketServer_SessionRejected(object sender, EventArgs e)
        {
            this.AddInfo("Session connect rejected");
        }

        private void SocketServer_SessionTimeout(object sender, TSessionEventArgs e)
        {
            this.AddInfo("Session timeout: ip " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_SessionConnected(object sender, TSessionEventArgs e)
        {
            this.AddInfo("Session connected: ip " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_SessionDisconnected(object sender, TSessionEventArgs e)
        {
            this.AddInfo("Session disconnected: ip " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_SessionReceiveException(object sender, TSessionEventArgs e)
        {
            this.AddInfo("Session receive exception: ip " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_SessionSendException(object sender, TSessionEventArgs e)
        {
            this.AddInfo("Session send exception: ip " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_SocketReceiveException(object sender, TSessionExceptionEventArgs e)
        {
            this.AddInfo("client socket receive exception: ip: " + e.SessionBaseInfo.IP + " exception message: " + e.ExceptionMessage);
        }

        private void SocketServer_SocketSendException(object sender, TSessionExceptionEventArgs e)
        {
            this.AddInfo("client socket send exception: ip: " + e.SessionBaseInfo.IP + " exception message: " + e.ExceptionMessage);
        }

        private void SocketServer_DatagramDelimiterError(object sender, TSessionEventArgs e)
        {
            this.AddInfo("datagram delimiter error. ip: " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_DatagramOversizeError(object sender, TSessionEventArgs e)
        {
            ;//this.AddInfo("datagram oversize error. ip: " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_DatagramReceived(object sender, TSessionEventArgs e)
        {
            ;//this.AddInfo("datagram received. ip: " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_DatagramrError(object sender, TSessionEventArgs e)
        {
            this.AddInfo("datagram error. ip: " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_DatagramHandled(object sender, TSessionEventArgs e)
        {
            ;//this.AddInfo("datagram handled. ip: " + e.SessionBaseInfo.IP);
        }

        private void SocketServer_DatabaseOpenException(object sender, TExceptionEventArgs e)
        {
            ;//this.AddInfo("open database exception: " + e.ExceptionMessage);
        }

        private void SocketServer_DatabaseCloseException(object sender, TExceptionEventArgs e)
        {
            ;//this.AddInfo("close database exception: " + e.ExceptionMessage);
        }

        private void SocketServer_DatabaseException(object sender, TExceptionEventArgs e)
        {
            ;//this.AddInfo("operate database exception: " + e.ExceptionMessage);
        }

        private void SocketServer_ShowDebugMessage(object sender, TExceptionEventArgs e)
        {
            ;//this.AddInfo("debug message: " + e.ExceptionMessage);
        }

        #endregion

        /// <summary>
        ///  添加日志文件 
        /// </summary>
        /// <param name="message"></param>
        private void AddInfo(string message)
        {
            string strFilePath = Application.StartupPath;
            try
            {
                strFilePath += @"/log/log.txt";
                System.IO.FileStream fs = new System.IO.FileStream(strFilePath, System.IO.FileMode.Append);
                System.IO.StreamWriter sw = new System.IO.StreamWriter(fs, System.Text.Encoding.Default);
                sw.WriteLine("'" + DateTime.Now.ToString() + "'\t'" + message + "\r\n");
                sw.Close();
                fs.Close();
            }
            catch (Exception ex)
            {
                ;
            }
            ;
            //if (lb_ServerInfo.Items.Count > 1000)
            //{
            //    lb_ServerInfo.Items.Clear();
            //}

            //lb_ServerInfo.Items.Add(message);
            //lb_ServerInfo.SelectedIndex = lb_ServerInfo.Items.Count - 1;
            //lb_ServerInfo.Focus();



        }


        public void sendAllSeachState(byte[] datagramBytes)
        {
            string datagramText = Encoding.ASCII.GetString(datagramBytes);
            m_socketServer.SendToAllSessions(datagramText);
        }


        public void sendSearchStateById(string dustcode, byte[] datagramBytes)
        {
            string datagramText = Encoding.ASCII.GetString(datagramBytes);
            Collection<TSessionCoreInfo> tlist = m_socketServer.SessionCoreInfoCollection;
            foreach (TSessionCoreInfo info in tlist)
            {
                if (info.Name == dustcode)
                {
                    m_socketServer.SendToSession(info.ID, datagramText);
                    break;
                }

            }

        }


        ~OperProcess()
        {
            if (m_socketServer != null)
                m_socketServer.Dispose();
        }
    }





    /// <summary>
    /// 测试用会话Session类
    /// </summary>
    public class TTestSession : TSessionBase
    {
        //定义委托s
        public delegate void SetNetValue(KeyValuePair<string, object> value);
        //定义接收数据事件
        public event SetNetValue setNetValue;

        /// <summary>
        /// 重写错误处理方法, 返回消息给客户端
        /// </summary>
        protected override void OnDatagramDelimiterError()
        {
            base.OnDatagramDelimiterError();

            //base.SendDatagram("datagram delimiter error");
        }

        /// <summary>
        /// 重写错误处理方法, 返回消息给客户端
        /// </summary>
        protected override void OnDatagramOversizeError()
        {
            base.OnDatagramOversizeError();

            //base.SendDatagram("datagram over size");
        }




        /// <summary>
        /// 框架打开
        /// </summary>
        /// <param name="qu"></param>
        /// <param name="lie"></param>
        /// <param name="jie"></param>
        /// <param name="cen"></param>
        /// <param name="LorR"></param>
        public bool  ArchiveOpen(int lie,int jie, int cen,int ce)
        {
            int k = 100;
         
                if (lie < PrjSerails.Global.FixedID &&lie >= 0)  //左边
                {
                    if (ce == 0)//左
                        if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveLeft(lie))
                            return true;
                        else
                            return false;
                    else
                    {
                        if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveRight(lie))
                            return true;
                        else
                            return false;
                    }
                }
                else if (lie> PrjSerails.Global.FixedID && lie <= PrjSerails.Global.ShelfNum)　//右边
                {
                    if (ce == 0)
                    {
                        if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveRight(lie))
                            return true;
                        else
                            return false;
                    }
                    else
                    {
                        return PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveLeft(lie);
                    }
                }
                else if (lie == PrjSerails.Global.FixedID)　//固定架
                {
                    if (PrjSerails.Global.FixedID == PrjSerails.Global.ShelfNum)
                    {
                        if (ce == 0)
                            return PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveRight(lie - 1);
                        else
                            return PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveLeft(lie - 1);
                    }
                    else if (PrjSerails.Global.FixedID == 1)
                    {
                        //new PrjSerails.UpControl().MoveRight(PrjSerails.Global.FixedID + 1);
                        return PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveRight(PrjSerails.Global.FixedID + 1);
                    }
                    else
                    {
                        if (ce == 0)
                            return PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveLeft(lie - 1);
                        else
                            return PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveRight(lie + 1);
                    }

                }
                return false;
               
        }

        /// <summary>
        /// 
        /// 
        /// </summary>
        protected override void AnalyzeDatagram(byte[] datagram)
        {
            string rStr = "";
            if (datagram.Length < 3)
                return;
            byte[] datagramBytes = new byte[datagram.Length - 2];
            Array.ConstrainedCopy(datagram, 1, datagramBytes, 0, datagram.Length - 2);
            PrjSerails.UpControl upControl = new PrjSerails.UpControl();
            string cmdstr = System.Text.Encoding.UTF8.GetString(datagramBytes);

            if (cmdstr.Contains("cmd1"))
            {
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.Enable())
                    rStr = "密集架解禁成功";
                else
                    rStr = "密集架解禁成功";                
                PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.ClearLampLocation();

            }
            else if(cmdstr.Contains("cmd2"))
            {
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                    rStr = "密集架禁止状态：操作失败";
                else
                {
                    PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.ClearLampLocation();
                    if(PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.VentilateMjj())
                        rStr = "密集架通风操作成功";
                    else
                        rStr = "密集架通风操作失败，请重试";
                }            
            }
            else if (cmdstr.Contains("cmd3"))
            {
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                    rStr = "密集架禁止状态：操作失败";
                else
                {
                    PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.ClearLampLocation();
                    if(PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.CloseMjj())
                        rStr = "密集架关架操作成功";
                    else
                        rStr = "密集架关架操作失败，请重试";
                }
            }
            else if(cmdstr.Contains("cmd4"))
            {
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isPower == false)
                    if(PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.PowerON())
                        rStr = "密集架打开电源操作成功";
                    else
                        rStr = "密集架打开电源操作失败，请重试";
                else
                    rStr = "密集架电源已打开";
            }
            else if (cmdstr.Contains("cmd5"))
            {
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isPower == true)
                    if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.PowerOFF())
                        rStr = "密集架关闭电源操作成功";
                    else
                        rStr = "密集架关闭电源操作失败，请重试";
                else
                    rStr = "密集架电源已关闭";

            }
            else if (cmdstr.Contains("cmd6"))
            {
                ;
            }
            else if (cmdstr.Contains("cmd7"))
            {
                try
                {
                    if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                        rStr = "密集架禁止状态：操作失败";
                    else
                    {
                        PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.ClearLampLocation();
                        string[] cmd = cmdstr.Split('#');
                        int moveId = Convert.ToInt32(cmd[1]);

                        if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveRight(moveId))
                            rStr = "密集架右移操作成功";
                        else
                            rStr = "密集架右移操作失败，请重试";
                    }
                }
                catch (Exception ex)
                {
                    rStr = "密集架右移操作失败，请检查："+ex.Message;
                }
            }
            else if (cmdstr.Contains("cmd8"))
            {
                try
                {
                    if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                        rStr = "密集架禁止状态：操作失败";
                    else
                    {
                        PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.ClearLampLocation();
                        string[] cmd = cmdstr.Split('#');
                        int moveId = Convert.ToInt32(cmd[1]);
                        if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MoveLeft(moveId))
                            rStr = "密集架左移操作成功";
                        else
                            rStr = "密集架左移操作失败，请重试";
                    }
                }
                catch (Exception ex)
                {
                    rStr = "密集架左移操作失败，请检查：" + ex.Message;
                }

            }
             else if (cmdstr.Contains("cmd9"))
            {
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                    rStr = "密集架禁止状态：操作失败";
                else
                {
                    PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.ClearLampLocation();
                    if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.Stop())
                        rStr = "密集架停止操作成功";
                    else
                        rStr = "密集架停止操作失败，请重试";
                }
            }
            else if (cmdstr.Contains("cmda"))
            {
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                    rStr = "密集架禁止状态：操作失败";
                else
                {
                    try
                    {
                        if (cmdstr.Length > 10)
                        {
                            string[] cmd = cmdstr.Split('#');
                            int lie = Convert.ToInt32(cmd[1]);
                            int jie = Convert.ToInt32(cmd[2]);
                            int cen = Convert.ToInt32(cmd[3]);
                            int ce = Convert.ToInt32(cmd[4]);
                            if(ArchiveOpen(lie, jie, cen, ce))
                                rStr = "打开文档操作成功";
                            else
                                rStr = "打开文档操作失败，请重试";
                            PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.OpenLampLocation(lie, jie, cen, ce);
                        }
                    }
                    catch(Exception ex)
                    {
                        rStr = "打开文档操作失败，请检查：" + ex.Message;
                    }
                }  

            }
            if (rStr.Length < 2)
            {
                rStr = "欢迎使用智能密集架控制管理系统";
                if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isPower == false)
                    rStr += ":电源处于关闭状态";
                else if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                    rStr += ":密集架处于禁止状态";
            }
            rStr = PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.AreaId.ToString() + "#" + rStr;
            if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isEnable == false)
                rStr = "0#" + rStr;
            else
                rStr = "1#"+rStr;
            if(PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isPower == false)
                rStr = "0#" + rStr;
            else
                rStr = "1#" + rStr;
            
            if(PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MasterState.isLock == true)
                rStr = rStr+"#1";
            else
                rStr = rStr + "#0";

            rStr = rStr + "#" + GetMjjState();
            rStr = PrjSerails.Global.MJJTEM.ToString() + "#" + PrjSerails.Global.MJJHUM.ToString() + "#" + Global.FixedID.ToString() + "#" + Global.ShelfNum.ToString() + "#" + rStr;
            base.SendDatagram(rStr);
        }

        private string GetMjjState()
        {
            String mjjStateStr = "";
            try
            {
                for (int i = 0; i < PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.ShelfNum; i++)
                {
                    if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MjjState1[i].leftPlace && PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MjjState1[i].rightPlace)
                        mjjStateStr += "11";
                    else if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MjjState1[i].leftPlace && PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MjjState1[i].rightPlace == false)
                        mjjStateStr += "10";
                    else if (PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MjjState1[i].leftPlace == false && PrjSerails.UI.Control.MainUnitClient.autowork.MJJ.MjjState1[i].rightPlace)
                        mjjStateStr += "01";
                    else
                        mjjStateStr += "00";
                    mjjStateStr += ":";
                }
                mjjStateStr = mjjStateStr.Substring(0, mjjStateStr.Length - 1);
                return mjjStateStr;
            }
            catch (Exception ex)
            {
                return "";
            }
        }

        /// <summary>
        /// 自定义的数据存储方法
        /// </summary>
        private void Store(byte[] value)
        {
            if (this.DatabaseObj == null)
            {
                return;
            }

            TTestAccessDatabase db = this.DatabaseObj as TTestAccessDatabase;
            db.Store(value, this);
        }
    }





    /// <summary>
    /// 传输
    /// </summary>
    public class TTestAccessDatabase : TOleDatabaseBase
    {
        private OleDbCommand m_command;  // 自定义的字段

        /// <summary>
        /// 重写 Open 方法
        /// </summary>
        public override void Open()
        {
            base.Open();  // 打开数据库

            m_command = new OleDbCommand();
            m_command.Connection = (OleDbConnection)this.DbConnection;

            // OleDbCommand 不能像 SqlCommand 在 CommandText 使用参数名称
            m_command.CommandText = "insert into DatagramTextTable(SessionIP, SessionName, DatagramSize) values (?, ?, ?)";

            m_command.Parameters.Add(new OleDbParameter("SessionIP", OleDbType.VarChar));
            m_command.Parameters.Add(new OleDbParameter("SessionName", OleDbType.VarChar));
            m_command.Parameters.Add(new OleDbParameter("DatagramSize", OleDbType.Integer));
        }

        /// <summary>
        /// 自定义数据存储方法
        /// </summary>
        public override void Store(byte[] datagramBytes, TSessionBase session)
        {
            //string datagramText = Encoding.ASCII.GetString(datagramBytes);
            try
            {
                m_command.Parameters["SessionIP"].Value = session.IP;
                m_command.Parameters["SessionName"].Value = session.Name;
                //m_command.Parameters["DatagramSize"].Value = datagramBytes.Length;

                m_command.ExecuteNonQuery();
            }
            catch (Exception err)
            {
                this.OnDatabaseException(err);
            }
        }
    }
}
